package com.onvif;

import com.onvif.soap.OnvifDevice;
import org.bytedeco.javacv.CanvasFrame;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.Frame;
import org.bytedeco.javacv.OpenCVFrameConverter;
import org.bytedeco.opencv.opencv_core.Mat;
import org.onvif.ver10.schema.Profile;

import javax.swing.*;
import javax.xml.soap.SOAPException;
import java.net.ConnectException;
import java.util.List;

public class myMain {

	private static final String INFO = "Commands:\n  \n  url: Get snapshort URL.\n  info: Get information about each valid command.\n  profiles: Get all profiles.\n  exit: Exit this application.";

	public static void main(String args[]) {
		//定义摄像头Ip
		String cameraAddress = "0.0.0.0";

		//定义访问摄像头网页需要的账号
		String user = "test";

		//定义访问摄像头网页需要的密码
		String password = "test";

		//实例化Onvif协议的设备信息
		//这里会进行初始化包括：检查设备是否在线、准备Soap消息头消息体发送webService接口获取设备能力等信息
		OnvifDevice cam;
		try {
			cam = new OnvifDevice(cameraAddress, user, password);
		}
		catch (ConnectException | SOAPException e1) {
			System.err.println("No connection to camera, please try again.");
			return;
		}
		System.out.println("Connection to camera successful!");

		//实例化后，调用api获取设备媒体信息（会存在主通道和子通道的区别，所以获取到的是个list）
		List<Profile> profiles = cam.getDevices().getProfiles();

		//一般第一个是主通道
		if(0<profiles.size()){
			//获取主通道的token信息 方便使用该token获取rtsp地址
			String token = profiles.get(0).getToken();
			try {
				String rtspStreamUri = cam.getMedia().getRTSPStreamUri(token);

				//集成了FFmpeg包
				//集成的时候还了解到了一个小历史ffmpeg耻辱柱事件~
				//简单说就是不乏大公司使用该开源框架，但是不遵守开源协议，然后被挂小黑板啦~
				FFmpegFrameGrabber grabber = null;
				try {
					//该框架其实是有一个第三方本地安装包的，然后使用方式就是调用命令行的方式
					//不过出了这个包就帮我们封装好命令行啦~
					grabber = FFmpegFrameGrabber.createDefault(rtspStreamUri);
				} catch (FFmpegFrameGrabber.Exception e) {
					e.printStackTrace();
				}

				// 使用tcp的方式
				grabber.setOption("rtsp_transport", "tcp");
				grabber.setImageWidth(960);
				grabber.setImageHeight(540);
				System.out.println("grabber start");
				try {
					grabber.start();
				} catch (FFmpegFrameGrabber.Exception e) {
					e.printStackTrace();
				}

				//创建桌面窗口，输出rtsp数据流
				CanvasFrame canvasFrame = new CanvasFrame("摄像机");
				canvasFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
				canvasFrame.setAlwaysOnTop(true);
				OpenCVFrameConverter.ToMat converter = new OpenCVFrameConverter.ToMat();
				while (true) {
					//持久化 输出摄像头画面
					Frame frame = null;
					try {
						frame = grabber.grabImage();
					} catch (FFmpegFrameGrabber.Exception e) {
						e.printStackTrace();
					}
					Mat mat = converter.convertToMat(frame);
					canvasFrame.showImage(frame);
				}
			} catch (ConnectException e) {
				e.printStackTrace();
			} catch (SOAPException e) {
				e.printStackTrace();
			}
		}
	}
}